﻿using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Admin.NET.Core;

namespace Admin.NET.Application
{
    /// <summary>
    /// 库位试图服务
    /// </summary>
    [ApiDescriptionSettings("仓库作业", Name = "LocationView", Order = 104)]
    [Route("api/[Controller]")]
    public class LocationViewService : IDynamicApiController, ITransient
    {
        private readonly IRepository<WmsArea, MasterDbContextLocator> _wmsAreaRep;
        private readonly IRepository<WmsPlace, MasterDbContextLocator> _wmsPlaceRep;
        private readonly IRepository<WmsMaterialStock, MasterDbContextLocator> _wmsMaterialStockRep;
        private readonly IRepository<WmsContainerPlace, MasterDbContextLocator> _wmsContainerPlaceRep; 
        private readonly IRepository<WmsContainer, MasterDbContextLocator> _wmsContainerRep;
        private readonly IRepository<WmsMaterialContainer, MasterDbContextLocator> _wmsMaterialContainerRep;

        /// <summary>
        /// 构造函数
        /// </summary>
        public LocationViewService(
            IRepository<WmsArea, MasterDbContextLocator> wmsAreaRep,
            IRepository<WmsPlace, MasterDbContextLocator> wmsPlaceRep,
            IRepository<WmsMaterialStock, MasterDbContextLocator> wmsMaterialStockRep,
            IRepository<WmsContainerPlace, MasterDbContextLocator> wmsContainerPlaceRe,
            IRepository<WmsContainer, MasterDbContextLocator> wmsContainerRep,
            IRepository<WmsMaterialContainer, MasterDbContextLocator> wmsMaterialContainer
        )
        {
            _wmsAreaRep = wmsAreaRep;
            _wmsPlaceRep = wmsPlaceRep;
            _wmsMaterialStockRep = wmsMaterialStockRep;
            _wmsContainerPlaceRep = wmsContainerPlaceRe;
            _wmsContainerRep = wmsContainerRep;
            _wmsMaterialContainerRep = wmsMaterialContainer;
        }

        /// <summary>
        /// 获取库区信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetArea")]
        public async Task<List<WmsArea>> GetArea()
        {
            var areaList = await _wmsAreaRep.Where(n => n.AreaStatus == CommonStatus.ENABLE && n.WorkShopType == LesWorkShopType.FAPAOCHEJIAN).ToListAsync();
            return areaList;
        }

        /// <summary>
        /// 根据库区获取巷道
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("GetAisle")]
        public async Task<object> GetPalceAisle([FromQuery] GetPalceAisleInput input)
        {
            
            var objList=await _wmsPlaceRep.Where(n => n.AreaId == input.Areaid).OrderBy(n=>n.Aisle).Select(n => n.Aisle).Distinct().ToArrayAsync();
            for (int i = 0; i < objList.Length-1; i++)
            {
                for (int j = 0; j < objList.Length-1; j++)
                {
                    int k = j + 1;
                    if (objList[j] >objList[k])
                    {
                        var temp = objList[k];
                        objList[k] = objList[j];
                        objList[j] = temp;
                    }
                }
            }
            return objList;
        }

        /// <summary>
        /// 根据库区和巷道获取排
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("GetPalceRowno")]
        public async Task<object> GetPalceRowno([FromQuery] GetPalceAisleRownoInput input)
        {
            var objList=await _wmsPlaceRep.Where(n => n.AreaId == input.Areaid && n.Aisle==input.Aisleid && n.WmsArea.WorkShopType == LesWorkShopType.FAPAOCHEJIAN).OrderBy(n => n.RowNo).Select(n => n.RowNo).Distinct().ToArrayAsync();

            for (int i = 0; i < objList.Length - 1; i++)
            {
                for (int j = 0; j < objList.Length - 1; j++)
                {
                    int k = j + 1;
                    if (objList[j] > objList[k])
                    {
                        var temp = objList[k];
                        objList[k] = objList[j];
                        objList[j] = temp;
                    }
                }
            }
            return objList;
        }

        /// <summary>
        /// 根据库区 排获取库位信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("GetPalceList")]
        public async Task<PalceInfoOtput> GetPalceList([FromQuery] GetPalceListInput input)
        {
            var palceList = await _wmsPlaceRep.DetachedEntities
                .Where(p => p.AreaId == input.Areaid)
                .Where(input.Aisleid != 0, p => p.Aisle == input.Aisleid)
                .Where(input.Rowno != 0, p => p.RowNo == input.Rowno)
                .ToListAsync();

            //获取有多少巷,排,列,层
            var Aisles = palceList.OrderBy(n => n.Aisle).Select(n => n.Aisle).Distinct().ToList();
        
            var locationDataList = new List<WareLocationAisleData>();
            //巷道
            foreach (var aisle in Aisles)
            {
                var aisleData = new WareLocationAisleData();
                aisleData.Aisle = aisle;
                aisleData.wareLocationRownoData = new List<WareLocationRownoData>();
                //排
                var RowNos = palceList.Where(p=>p.Aisle==aisle).OrderBy(n => n.RowNo).Select(n => n.RowNo).Distinct().ToList();
                foreach (var row in RowNos)
                {
                    var rownoData = new WareLocationRownoData();
                    rownoData.Rowno = row;
                    rownoData.wareLocationLayerData = new List<WareLocationLayerData>();
                    //层
                    var LayerNo = palceList.Where(p=>p.Aisle==aisle && p.RowNo==row).OrderByDescending(n => n.LayerNo).Select(n => n.LayerNo).Distinct();
                    foreach (var lay in LayerNo)
                    {
                        var layerData = new WareLocationLayerData();
                        layerData.Layer = lay;
                        layerData.wareLocationColumnNoData = new List<PalceDetail>();
                        //列
                        var ColumnNos = palceList.Where(p=>p.Aisle==aisle && p.RowNo==row).OrderByDescending(n => n.ColumnNo).Select(n => n.ColumnNo).Distinct();
                        foreach (var col in ColumnNos)
                        {
                            var wareLocationMdoel = palceList.Where(p =>p.Aisle==aisle && p.RowNo == row && p.LayerNo == lay && p.ColumnNo == col).FirstOrDefault();
                            if (wareLocationMdoel != null)
                            {
                                var locationDetail = new PalceDetail()
                                {
                                    Id = wareLocationMdoel.Id,
                                    RowNo = wareLocationMdoel.RowNo,
                                    ColumnNo = wareLocationMdoel.ColumnNo,
                                    LayerNo = wareLocationMdoel.LayerNo,
                                    PlaceCode = wareLocationMdoel.PlaceCode,
                                    Islock = wareLocationMdoel.Islock,
                                    EmptyContainer = wareLocationMdoel.EmptyContainer,
                                    PlaceStatus = wareLocationMdoel.PlaceStatus,
                                };
                                layerData.wareLocationColumnNoData.Add(locationDetail);
                            }
                            else
                            {
                                layerData.wareLocationColumnNoData.Add(null);
                            }
                        }
                        rownoData.wareLocationLayerData.Add(layerData);
                    }
                    aisleData.wareLocationRownoData.Add(rownoData);
                }
                locationDataList.Add(aisleData);
            }

            return new PalceInfoOtput()
            {
                countNum = palceList.Count,
                cunhuoNum = palceList.Where(n => n.PlaceStatus == PlaceStatus.CUNHUO).Count(),
                emptyNum = palceList.Where(n => n.PlaceStatus == PlaceStatus.KONGXIAN).Count(),
                DaiRuNum = palceList.Where(n => n.PlaceStatus == PlaceStatus.DAIRU).Count(),
                DaichuNum = palceList.Where(n => n.PlaceStatus == PlaceStatus.DAICHU).Count(),
                emptyContainerNum = palceList.Where(p => p.EmptyContainer == YesOrNot.Y && p.PlaceStatus == PlaceStatus.CUNHUO).Count(),
                materialNum = palceList.Where(p => p.EmptyContainer == YesOrNot.N && p.PlaceStatus == PlaceStatus.CUNHUO).Count(),
                lockNum = palceList.Where(p => p.Islock == YesOrNot.Y).Count(),
                PalceDetails = locationDataList,
            };
        }

        /// <summary>
        /// 根据库位获取对应信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("GetMaterialDetail")]
        [UnifyResult(typeof(MaterialDetailsOutput))]
        public async Task<object> GetMaterialDetail([FromQuery] GetMaterialDetailInput input)
        {
            var palceModel = await _wmsPlaceRep.FirstOrDefaultAsync(p => p.Id == input.Id);
            if (palceModel == null) return XnRestfulResultProvider.RESTfulMesaage("库位信息不存在!");
            var MaterialStockList = await _wmsMaterialStockRep.Where(p => p.PlaceCode == palceModel.PlaceCode).ToListAsync();
            var model = new MaterialDetailsOutput()
            {
                PalceDetails = palceModel.Adapt<PalceDetail>()
            };
            if (MaterialStockList.Count > 0)
            {
                model.Containercode = MaterialStockList.FirstOrDefault().ContainerCode;
                model.WmsMaterialStocks = MaterialStockList;
            }
            return XnRestfulResultProvider.RESTfulResult(model);
        }

        /// <summary>
        /// 修改库位锁定信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("UpdatePalceIslock")]
        [UnifyResult(typeof(object))]
        public async Task<object> UpdatePalceIslock([FromQuery] GetMaterialDetailInput input)
        {
            var palceModel = await _wmsPlaceRep.FirstOrDefaultAsync(p => p.Id == input.Id);
            if (palceModel == null) return XnRestfulResultProvider.RESTfulMesaage("库位信息不存在!");
            if (palceModel.Islock == YesOrNot.Y)
            {
                palceModel.Islock = YesOrNot.N;
            }
            else
            {
                palceModel.Islock = YesOrNot.Y;
            }
            await _wmsPlaceRep.UpdateAsync(palceModel);
            return XnRestfulResultProvider.RESTfulResult();
        }

        /// <summary>
        /// 将库位置为空闲
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("UpdatePalceKongXian")]
        [UnifyResult(typeof(object))]
        [UnitOfWork]
        public async Task<object> UpdatePalceKongXian([FromQuery] GetMaterialDetailInput input)
        {
            var palceModel = await _wmsPlaceRep.FirstOrDefaultAsync(p => p.Id == input.Id);
            if (palceModel == null) return XnRestfulResultProvider.RESTfulMesaage("库位信息不存在!");
            palceModel.PlaceStatus = PlaceStatus.KONGXIAN;
            await _wmsPlaceRep.UpdateAsync(palceModel);

            var materialStockModel = await _wmsMaterialStockRep.Where(p => p.PlaceCode == palceModel.PlaceCode).FirstOrDefaultAsync();
            if (materialStockModel != null)
            {
                await _wmsMaterialStockRep.DeleteAsync(materialStockModel);
            }
            var containerPlaceModel = await _wmsContainerPlaceRep.Where(p => p.PlaceCode == palceModel.PlaceCode && p.ContainerPlaceStatus == CommonStatus.ENABLE).FirstOrDefaultAsync();
            if (containerPlaceModel != null)
            {
                containerPlaceModel.ContainerPlaceStatus = CommonStatus.DISABLE;
                await _wmsContainerPlaceRep.UpdateAsync(containerPlaceModel);

                var wmsMaterialContainerModal = await _wmsMaterialContainerRep.FirstOrDefaultAsync(p => p.ContainerCode == containerPlaceModel.ContainerCode && p.BindStatus == CommonStatus.ENABLE);
                if (containerPlaceModel != null) return XnRestfulResultProvider.RESTfulMesaage("物料托盘信息不存在!");
                containerPlaceModel.ContainerPlaceStatus = CommonStatus.DISABLE;
                await _wmsMaterialContainerRep.UpdateAsync(wmsMaterialContainerModal);

                var containerModel = await _wmsContainerRep.FirstOrDefaultAsync(p => p.ContainerCode == containerPlaceModel.ContainerCode);
                if (containerModel != null)
                {
                    containerModel.ContainerStatus = ContainerStatus.KOUXIAN;
                    await _wmsContainerRep.UpdateAsync(containerModel);
                }
            }
            return XnRestfulResultProvider.RESTfulResult();
        }
    }
}
